<?php
namespace app\common\helper;

use think\Exception;

/**
 * 七牛图片鉴别审查
 *
 * Class QiNiuImgCheck
 * @package app\common\helper
 */
class QiNiuImgCheck {

    const API_CHECK_SEXY_URL = 'http://ai.qiniuapi.com/v1/pulp';

    private $_accessKey;
    private $_secretKey;
    public static $err_msg;

    public function __construct() {
        $this->_accessKey = config('Qiniuyun_conf.AccessKey');
        $this->_secretKey = config('Qiniuyun_conf.SecretKey');
    }

    /**
     * 验黄
     *
     * @param $img_url
     * @return bool
     */
    public function checkSexy($img_url) {
        $request_data = [
            'data' => [
                'uri' => $img_url,
            ]
        ];
        $auth_sign = $this->getAuth($request_data);
        $res = $this->request_by_curl($request_data, $auth_sign);
        return $res;
    }

    /**
     * 得到最终管理凭证（token）
     * @param $request_data
     * @return string
     */
    public function getAuth($request_data) {
        $body = json_encode($request_data);
        $data = $this->formatAuthData(self::API_CHECK_SEXY_URL, 'POST', $body, 'application/json');
        $sign = $this->sign($data);
        return 'Qiniu ' . $this->_accessKey . ':' . $sign;
    }

    /**
     * 构建auth鉴权的数据
     *
     * @param $url
     * @param $method
     * @param null $body
     * @param null $contentType
     * @return string
     */
    public function formatAuthData($url, $method, $body = null, $contentType = null)
    {
        $urlItems = parse_url($url);
        $host = $urlItems['host'];

        if (isset($urlItems['port'])) {
            $port = $urlItems['port'];
        } else {
            $port = '';
        }

        $path = $urlItems['path'];
        if (isset($urlItems['query'])) {
            $query = $urlItems['query'];
        } else {
            $query = '';
        }

        //write request uri
        $toSignStr = $method . ' ' . $path;
        if (!empty($query)) {
            $toSignStr .= '?' . $query;
        }

        //write host and port
        $toSignStr .= "\nHost: " . $host;
        if (!empty($port)) {
            $toSignStr .= ":" . $port;
        }

        //write content type
        if (!empty($contentType)) {
            $toSignStr .= "\nContent-Type: " . $contentType;
        }

        $toSignStr .= "\n\n";

        //write body
        if (!empty($body)) {
            $toSignStr .= $body;
        }

        return $toSignStr;
    }

    /**
     *  对数据进行签名运算并对结果base64处理
     * @param $data
     * @return string
     */
    public function sign($data)
    {
        $h_mac = hash_hmac('sha1', $data, $this->_secretKey, true);
        return $this->base64_urlSafeEncode($h_mac);
    }

    function base64_urlSafeEncode($data)
    {
        $find = array('+', '/');
        $replace = array('-', '_');
        return str_replace($find, $replace, base64_encode($data));
    }

    public function request_by_curl($request_data, $auth_sign)
    {
        $headers = array();
        $headers[] = 'Content-Type:application/json';
        $url_arr = parse_url(self::API_CHECK_SEXY_URL);
        $headers[] = 'Host:' . $url_arr['host'];
        $headers[] = 'Authorization:' . $auth_sign;
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, self::API_CHECK_SEXY_URL);
        //curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($request_data));
        //curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);

        try {
            $data = curl_exec($ch);
            $err = curl_error($ch);
            if (!empty($err)) {
                self::$err_msg = '请求失败：'. $err;
                throw new Exception('error');
            }
            curl_close($ch);
        } catch (\Exception $e) {
            return false;
        }
        $data = json_decode($data, true);
        return $data['result'];
    }

}